/**********************************************************************************************************************
 *
 * Project:    mGameEngine
 * File:       perspectivecamera.cpp
 * Author:     karooolek
 * Created on: 2009-04-03
 *
 **********************************************************************************************************************/

#include "perspectivecamera.h"
#include <GL/glu.h>

namespace mGameEngine
{
namespace Graphics
{

PerspectiveCamera::PerspectiveCamera(float fov,
        float ratio, bool autoRatio,
        float nearClip, float farClip) :
    Camera(ratio, autoRatio, nearClip, farClip),
    _fov(fov)
{
}

PerspectiveCamera::~PerspectiveCamera()
{
}

bool PerspectiveCamera::isInCamera(const Sphere & sphere) const
{
    const Position &pos = sphere.getCenter();
    float r = sphere.getRadius();

    // near and far planes clipping
    if(-pos.z < _nearClip - r || -pos.z > _farClip + r)
    {
        return false;
    }

    // vertical fov clipping
    float phi = 0.5f * _fov;
    if(abs(pos.y) > -pos.z * tan(phi) + r / cos(phi))
    {
        return false;
    }

    // horizontal fov clipping
    float ratio = _ratio;

    if(_autoRatio)
    {
        int viewport[4];
        glGetIntegerv(GL_VIEWPORT, viewport);
        ratio = float(viewport[2]) / float(viewport[3]);
    }

    float theta = atan(ratio * tan(phi));
    if(abs(pos.x) > -pos.z * tan(theta) + r / cos(theta))
    {
        return false;
    }

    return true;
}

float PerspectiveCamera::getProjectedSize(const Sphere &sphere) const
{
    float l = sphere.getCenter().z;
    float r = sphere.getRadius();

    return r / (fabs(l) * tan(0.5f * _fov));
}

void PerspectiveCamera::use() const
{
    float ratio = _ratio;

    if(_autoRatio)
    {
        int viewport[4];
        glGetIntegerv(GL_VIEWPORT, viewport);
        ratio = float(viewport[2]) / float(viewport[3]);
    }

    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(deg(_fov), ratio, _nearClip, _farClip);
}

}
}

